#include "udpServer.hpp"
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <memory>
using namespace std;
using namespace Server;

const string dictTxt = "./dict.txt";

static void Usage(string proc)
{
    cout << "\nUsage:\n\t" << proc << " lock_port\n\n";
}

// demo2 解耦的好处，可以快速修改代码
void execCommand(const int &sockfd, const string &clientip, const uint16_t &clientport, const string &cmd)
{
    // 1. 解析 cmd   -> ls -l -a
    // 2. 如果必要，我们可以使用fork

    // 这里直接调用 popen

    // 防止恶意命令
    if (cmd.find("rm") != string::npos || cmd.find("mv") != string::npos || cmd.find("rmdir") != string::npos)
    {
        cout << clientip << ":" << clientport << " 正在做非法操作" << endl;
        return;
    }

    string response_message;
    FILE *fd = popen(cmd.c_str(), "r");
    if (nullptr == fd)
        response_message = cmd + "exec file";

    char line[1024];
    while (fgets(line, sizeof(line), fd))
    {
        response_message += line;
    }
    pclose(fd);

    // cout << response_message.c_str() << endl;
    //  2.将信息转发回客户端
    struct sockaddr_in client;
    bzero(&client, sizeof(client));

    client.sin_family = AF_INET;
    client.sin_port = htons(clientport);
    client.sin_addr.s_addr = inet_addr(clientip.c_str());
    sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr *)&client, sizeof(client));
}

// ./UdpServer ip prot
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }
    uint16_t port = atoi(argv[1]);

    std::unique_ptr<udpserver> usvr(new udpserver(execCommand, port));
    usvr->initServer();
    usvr->start();
    return 0;
}